﻿using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

namespace Nemerle2.Compiler
{
  /// <summary>
  /// Компилируемый проект. Хранит дерево типов состоящее из пространств имен
  /// и содержащихся в них типов, а так же другую общую для проекта информацию.
  /// http://code.google.com/p/nemerle-2/wiki/NProject
  /// </summary>
  public class NProject : IReferencedAssembly
  {
    public this(engine : NSolution)
    {
      Engine        = engine;
      TypesTreeRoot = TypesTreeNode.NamespaceReference(this);
      Env           = GlobalEnv(this, array["Nemerle.Core", // open default namespaces
                                            "Nemerle.Core.option"]);
    }

    public Engine           : NSolution     { get}
    public TypesTreeRoot    : TypesTreeNode { get; private set; }
    /// Отображение пути (строки разделенной точками) на TypesTreeNode. Позволяет быстро получить TypesTreeNode по пути.
    _typesTreePathCache     : Hashtable[string, TypesTreeNode] = Hashtable();
    public Env              : GlobalEnv;

    #region IReferencedAssembly impl

    public CustomAttributes  : ICustomAttributes      { get; private set; }
    public TopLevelTypes     : IEnumerable[ITypeInfo] { get { throw System.NotImplementedException() } }
    public AllTypes          : IEnumerable[ITypeInfo] { get { throw System.NotImplementedException() } }
    ///NProject always return empty list of macros since macros must be compiled
    public Macros            : list[IMacroInfo]          { get { [] } }
    public Msgs              : list[Msg]              { get { throw NotImplementedException() } }

    public ImagePath         : string                 { get { throw NotImplementedException() } }
    public FullName          : string                 { get { "NProject" } }
    public Name              : string                 { get { "NProject" } }
    public Flags             : AssemblyNameFlags      { get { AssemblyNameFlags.EnableJITcompileOptimizer } }
    
    public event Changed : EventHandler;
    
    public Init() : void
    {
      throw NotImplementedException()
    }

    #endregion

    public Sources                    : list[string] { get; private set; }
    public ReferencedAssemblies       : list[string] { get; private set; }
    public ReferencedMacroAssemblies  : list[string] { get; private set; }
    public LoadedAssemblies           : Seq [IReferencedAssembly]  {get; private set;}

    public Load(sources : list[string], referencedAssemblies : list[string], referencedMacroAssemblies : list[string]) : array[Msg]
    {
      Sources = sources; ReferencedAssemblies = referencedAssemblies; ReferencedMacroAssemblies = referencedMacroAssemblies;

      LoadedAssemblies = Engine.LoadRequest(referencedAssemblies);
      
      Changed?.Invoke(this, EventArgs.Empty);
      array[]
    }
    
    public LookupType(_name : string, _typeParamsCount : int) : ITypeInfo
    {
      throw NotImplementedException()
    }
    public Namespaces : ReadOnlyArray[string * ReadOnlyArray[ITypeInfo] * ReadOnlyArray[IMacroInfo]]
    {
    	get { throw System.NotImplementedException() }
    }
    
  }
}
